Skip to content

refactor: SimulationCfg.play_retargeted_keys() (ROADMAP §9 PR R3.2 / ADR-0005) - #91

Merged
KraHsu merged 1 commit into
devfrom
feat/r3-2-play-retargeted-keys
May 22, 2026
Merged

KraHsu merged 1 commit into
devfrom
feat/r3-2-play-retargeted-keys

Conversation

@KraHsu

@KraHsu KraHsu commented May 22, 2026

Copy link
Copy Markdown
Owner

Summary

  • Lands ROADMAP §9 PR R3.2 — second of two sub-PRs in ADR-0005. Completes Phase R3.
  • Moves the play-mode shortcut-retargeting key list off cli/__init__.py:_PLAY_RETARGETED_KEYS onto SimulationCfg.play_retargeted_keys().
  • No behaviour change. genelab play --help byte-identical (R0.1 gate); configs.py stays torch-free (invariant ci/per job cache suffix and pages enablement #5).

What changed

File Change
src/genelab/configs.py +SimulationCfg.play_retargeted_keys() -> tuple[str, ...] static method (+19 LoC). Returns the four env.simulation.{vis,gpu,steps,dt} override paths verbatim.
src/genelab/cli/__init__.py Play-mode retarget loop calls SimulationCfg.play_retargeted_keys(); _PLAY_RETARGETED_KEYS constant removed; SimulationCfg added to the existing module-top from genelab.configs import …. Net −10.
tests/test_configs.py (new, 3 tests) Exact ordered set; every key names a real SimulationCfg field; class/instance call equivalence.
CHANGELOG.md [Unreleased] · Changed entry.

Design decision (confirmed with maintainer)

Returns the full paths verbatim (env.simulation.*) rather than bare field names — faithful to ADR-0005's "replaces _PLAY_RETARGETED_KEYS" framing, leaving the CLI use-site unchanged except for the constant → method swap. The minor smell (a SimulationCfg method referencing its env.simulation. mount path) was accepted over the alternative (bare names + CLI composes the prefix), which would have changed the use-site logic.

Reference audit (per CLAUDE.md §9.1 rule 1)

_PLAY_RETARGETED_KEYS had a single use site — the play-mode env. → play_env. retarget loop. Removed. SimulationCfg added to the existing from genelab.configs import apply_overrides line (now import SimulationCfg, apply_overrides); cli → configs is the allowed layering direction.

Local verification

  • uv run pytest tests/test_configs.py — 3 passed
  • uv run pytest tests/test_cli_help_snapshots.py — 11 passed (byte-identical) — R0.1 gate confirms no --help change
  • python -c "import sys; import genelab.configs; assert 'torch' not in sys.modules" — configs.py torch-free (invariant ci/per job cache suffix and pages enablement #5)
  • uv run ruff check && uv run ruff format --check — All checks passed
  • uv run pyright — 0 errors, 0 warnings, 0 informations
  • uv run pytest — 395 passed (was 392; +3 from the new test)
  • uv run lint-imports — Contracts: 2 kept, 2 broken (unchanged — cli → configs, allowed direction)

ADR-0005 §10 completion criteria

Criterion Status
New classmethods tested ✅ R3.1 EvalCallbackCfg.from_args (5 tests), R3.2 SimulationCfg.play_retargeted_keys (3 tests)
Snapshot diff empty ✅ 11/11 byte-identical
cli/__init__.py shrinks ≥ 35 LoC ⚠️ −31 actual (1051 → 1020 across R3.1 + R3.2). The ≥35 was an ADR estimate; the actual parse logic was a touch smaller. The substantive goal — both parsers (--eval-* args, play-retarget keys) now domain-owned — is met.

Phase R3 complete on merge

Sub-PR Status
R3.1 — EvalCallbackCfg.from_args ✅ PR #90 merged (6b97f6e)
R3.2 — SimulationCfg.play_retargeted_keys ✅ this PR

R3 was the gate for R4 (CLI decomposition), which can now proceed (serial after R3 per §9.2).

Note on the importlinter baseline

Like R3.1, R3.2 is cli → configs (allowed direction) and does not reduce the importlinter baseline (still 2 kept / 2 broken). The rl.eval_callback → cli._eval violation remains a separate follow-up (move eval_task's domain core into rl/).

Rollback

git revert <merge-sha>. Restores _PLAY_RETARGETED_KEYS in cli/__init__.py and removes the method + test.

🤖 Generated with Claude Code

… (ROADMAP §9 PR R3.2 / ADR-0005)

Move the play-mode shortcut-retargeting key list off the private
`cli/__init__.py:_PLAY_RETARGETED_KEYS` constant onto
`SimulationCfg.play_retargeted_keys()` (static method on the domain
config). The CLI's `env.` → `play_env.` retarget loop in play mode
now calls the method; the set of play-retargetable simulation override
paths lives next to the SimulationCfg fields the --vis / --gpu /
--steps / --dt shortcuts target.

Returns the four paths verbatim (`env.simulation.{vis,gpu,steps,dt}`)
so the CLI use-site is unchanged except for the constant → method swap
— the lowest-risk faithful replacement per ADR-0005's framing. All
four are real SimulationCfg fields (test_configs.py asserts this).

Completes ADR-0005 / R3 (R3.1 EvalCallbackCfg.from_args shipped in
PR #90; this is R3.2).

New `tests/test_configs.py` (3 tests): exact ordered set, every key
names a real SimulationCfg field, and class/instance call equivalence.

Reference audit (per CLAUDE.md §9.1 rule 1): `_PLAY_RETARGETED_KEYS`
had a single use site (the play-mode retarget loop); removed.
`SimulationCfg` added to the existing module-top
`from genelab.configs import …` line in cli/__init__.py (cli → configs
is the allowed layering direction).

Verified: ruff ✓, pyright 0/0/0, full suite 395 passed (was 392; +3
from test_configs.py), `genelab play --help` snapshots byte-identical
(R0.1 gate), configs.py stays torch-free at import (invariant #5),
lint-imports baseline unchanged at 2 kept / 2 broken.

cli/__init__.py LoC: 1051 (refactor start) → 1020 after R3.1 + R3.2
(−31). ADR-0005 §10 estimated ≥35; the actual parse logic was a touch
smaller. Both parsers (eval-callback args, play-retarget keys) are now
domain-owned, which was the substantive goal.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@KraHsu
KraHsu merged commit 03f480b into dev May 22, 2026
3 checks passed
@KraHsu
KraHsu deleted the feat/r3-2-play-retargeted-keys branch May 22, 2026 03:54
KraHsu added a commit that referenced this pull request Jun 5, 2026
refactor: SimulationCfg.play_retargeted_keys() (ROADMAP §9 PR R3.2 / ADR-0005)
KraHsu added a commit that referenced this pull request Jun 5, 2026
…erged)

Mark Phase R3 (domain-owned parsing, ADR-0005) complete (PRs #90/#91)
and Phase R4 (CLI decomposition, ADR-0004) in progress with R4.1 merged
(PR #92). Records the R3.1/R3.2/R4.1 shipped entries, test results, the
unchanged 2-kept/2-broken/21 importlinter baseline, and the new __all__
lesson from R4.1.

Corrects the prior wrong claim that R3 would clear the
`rl.eval_callback -> cli._eval` violation: R3 moved a parser in the
allowed cli->rl direction; the violation is the rl->cli runtime import
of eval_task inside run_with_eval_callback, untouched by R3. No R-phase
as currently scoped reduces the baseline — flagged as a dedicated
follow-up gating R7.

Sets R4.2 (cli/_multi_seed.py) as the next slice.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant